home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1994 February: Tool Chest / Dev.CD Feb 94.toast / Tool Chest / Development Platforms / AppsToGo / AppsToGo.src / DTS.Lib / AERequired.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-06-18  |  10.1 KB  |  352 lines  |  [TEXT/MPS ]

  1. /*
  2. ** Apple Macintosh Developer Technical Support
  3. **
  4. ** Program:        DTS.Lib
  5. ** File:        AERequired.c
  6. ** Written by:  Eric Soldan
  7. **
  8. ** Copyright © 1990-1991 Apple Computer, Inc.
  9. ** All rights reserved.
  10. **
  11. ** This code implements the required AppleEvents, specific to DTS.Lib.
  12. */
  13.  
  14. /* You may incorporate this sample code into your applications without
  15. ** restriction, though the sample code has been provided "AS IS" and the
  16. ** responsibility for its operation is 100% yours.  However, what you are
  17. ** not permitted to do is to redistribute the source as "DSC Sample Code"
  18. ** after having made changes. If you're going to re-distribute the source,
  19. ** we require that you make it clear in the source that the code was
  20. ** descended from Apple Sample Code, but that you've made changes. */
  21.  
  22.  
  23.  
  24. /*****************************************************************************/
  25.  
  26.  
  27.  
  28. #include "DTS.Lib2.h"
  29. #include "DTS.Lib.protos.h"
  30.  
  31. #ifndef __GESTALTEQU__
  32. #include <GestaltEqu.h>
  33. #endif
  34.  
  35.  
  36.  
  37. /*****************************************************************************/
  38.  
  39.  
  40.  
  41. #define kTimeOutInTicks (60 * 30)    /* 30 second timeout. */
  42.  
  43. static pascal OSErr    DoAEOpenApplication(AppleEvent *message, AppleEvent *reply, long refcon);
  44. static pascal OSErr    DoAEOpenDocuments(AppleEvent *message, AppleEvent *reply, long refcon);
  45. static pascal OSErr    DoAEPrintDocuments(AppleEvent *message, AppleEvent *reply, long refcon);
  46. static pascal OSErr    DoAEQuitApplication(AppleEvent *message, AppleEvent *reply, long refcon);
  47. static OSErr        OpenDocEventHandler(AppleEvent *message, AppleEvent *reply, short mode);
  48.  
  49.  
  50.  
  51. /*****************************************************************************/
  52.  
  53.  
  54.  
  55. static AEHandler keywordsToInstall[] = {
  56.     { kCoreEventClass,        kAEOpenApplication,        (ProcPtr)DoAEOpenApplication },
  57.     { kCoreEventClass,        kAEOpenDocuments,        (ProcPtr)DoAEOpenDocuments },
  58.     { kCoreEventClass,        kAEPrintDocuments,        (ProcPtr)DoAEPrintDocuments },
  59.     { kCoreEventClass,        kAEQuitApplication,        (ProcPtr)DoAEQuitApplication }
  60.         /* The above are the four required AppleEvents. */
  61. };
  62.  
  63. Boolean        gHasAppleEvents = false;
  64. Boolean        gHasPPCToolbox  = false;
  65.  
  66. extern TreeObjHndl    gWindowFormats;
  67.  
  68.  
  69.  
  70. /*****************************************************************************/
  71.  
  72.  
  73.  
  74. extern Boolean        gQuitApplication, gNoDefaultDocument, gInBackground;
  75. extern short        gPrintPage;
  76.  
  77. extern Cursor        *gCursorPtr;
  78. extern OSType        gAppWindowType;
  79.  
  80.  
  81.  
  82. /*****************************************************************************/
  83. /*****************************************************************************/
  84.  
  85.  
  86.  
  87. /* Intializes AppleEvent dispatcher table for the required events.  It also
  88. ** determines if the machine is PPCBrowser and AppleEvent capable.  If so,
  89. ** the booleans gHasAppleEvents and gHasPPCToolbox are set true.  This function
  90. ** must be the first AppleEvents initialization DTS.framework function called, as the
  91. ** other functions depend on the booleans being set correctly. */
  92.  
  93. #pragma segment AppleEvents
  94. OSErr    InitRequiredAppleEvents(void)
  95. {
  96.     OSErr    err;
  97.     long    result;
  98.     short    i;
  99.  
  100.     gHasPPCToolbox  = (Gestalt(gestaltPPCToolboxAttr, &result) ? false : result != 0);
  101.     gHasAppleEvents = (Gestalt(gestaltAppleEventsAttr, &result) ? false : result != 0);
  102.  
  103.     if (gHasAppleEvents) {
  104.         for (i = 0; i < (sizeof(keywordsToInstall) / sizeof(AEHandler)); ++i) {
  105.             err = AEInstallEventHandler(
  106.                 keywordsToInstall[i].theEventClass,    /* What class to install.  */
  107.                 keywordsToInstall[i].theEventID,    /* Keywords to install.    */
  108.                 keywordsToInstall[i].theHandler,    /* The AppleEvent handler. */
  109.                 0L,                                    /* Unused refcon.           */
  110.                 false                                /* Only for our app.       */
  111.             );
  112.             if (err) {
  113.                 HCenteredAlert(rErrorAlert, nil, (ModalFilterProcPtr)AlertFilter);
  114.                 return(err);
  115.             }
  116.         }
  117.     }
  118.  
  119.     return(noErr);
  120. }
  121.  
  122.  
  123.  
  124. /*****************************************************************************/
  125.  
  126.  
  127.  
  128. /* This function opens a new DTS.framework document due to an AppleEvents request. */
  129.  
  130. #pragma segment AppleEvents
  131. static pascal OSErr    DoAEOpenApplication(AppleEvent *message, AppleEvent *reply, long refcon)
  132. {
  133. #pragma unused (message, reply, refcon)
  134.  
  135.     FileRecHndl    frHndl;
  136.     OSErr        err;
  137.     short        i;
  138.     TreeObjHndl    wobj;
  139.     long        attr;
  140.  
  141.     gCursorPtr = nil;
  142.         /* Force re-calc of cursor region and cursor to use. */
  143.  
  144.     err = DoOpenApplication();
  145.     if (!err) {
  146.         if (gWindowFormats) {
  147.             for (i = (*gWindowFormats)->numChildren; i;) {
  148.                 wobj = GetChildHndl(gWindowFormats, --i);
  149.                 attr = mDerefWFMT(wobj)->attributes;
  150.                 if (!(attr & kwRuntimeOnlyDoc)) {
  151.                     if (attr & kwAutoNew) {
  152.                         err = NewDocumentWindow(&frHndl, mDerefWFMT(wobj)->sfType, true);
  153.                         if (err) break;
  154.                     }
  155.                 }
  156.             }
  157.         }
  158.         else {
  159.             if (!gNoDefaultDocument) {
  160.                 err = NewDocument(&frHndl, gAppWindowType, true);
  161.                 if (!err)
  162.                     if (frHndl)
  163.                         if (err = DoNewWindow(frHndl, nil, FrontWindow(), (WindowPtr)-1))
  164.                             DisposeDocument(frHndl);
  165.             }
  166.         }
  167.     }
  168.  
  169.     return(err);
  170. }
  171.  
  172.  
  173.  
  174. /*****************************************************************************/
  175.  
  176.  
  177.  
  178. /* This function opens existing DTS.framework documents due to an AppleEvents request. */
  179.  
  180. #pragma segment AppleEvents
  181. static pascal OSErr    DoAEOpenDocuments(AppleEvent *message, AppleEvent *reply, long refcon)
  182. {
  183. #pragma unused (refcon)
  184.  
  185.     gCursorPtr = nil;        /* Force re-calc of cursor region and cursor to use. */
  186.     return(OpenDocEventHandler(message, reply, 0));
  187.         /* The 0 means regular open document. */
  188. }
  189.  
  190.  
  191.  
  192. /*****************************************************************************/
  193.  
  194.  
  195.  
  196. /* This function prints DTS.framework documents due to an AppleEvents request. */
  197.  
  198. #pragma segment AppleEvents
  199. static pascal OSErr    DoAEPrintDocuments(AppleEvent *message, AppleEvent *reply, long refcon)
  200. {
  201. #pragma unused (refcon)
  202.  
  203.     short                openMode;
  204.     ProcessSerialNumber    cpsn, fpsn;
  205.     Boolean                procsSame;
  206.  
  207.     gCursorPtr = nil;        /* Force re-calc of cursor region and cursor to use. */
  208.  
  209.     openMode = 1;
  210.     if (!AEInteractWithUser(kTimeOutInTicks, nil, nil))
  211.         ++openMode;
  212.  
  213.     GetCurrentProcess(&cpsn);        /* We may have been moved to the front. */
  214.     GetFrontProcess(&fpsn);
  215.     SameProcess(&cpsn, &fpsn, &procsSame);
  216.     gInBackground = !procsSame;
  217.  
  218.     return(OpenDocEventHandler(message, reply, openMode));
  219.         /* openMode is either 1 or 2, depending if user interaction is okay. */
  220. }
  221.  
  222.  
  223.  
  224. /*****************************************************************************/
  225.  
  226.  
  227.  
  228. /* This function sets a quit flag so that DTS.framework will quit due to an
  229. ** AppleEvents request. */
  230.  
  231. #pragma segment AppleEvents
  232. static pascal OSErr    DoAEQuitApplication(AppleEvent *message, AppleEvent *reply, long refcon)
  233. {
  234. #pragma unused (message, reply, refcon)
  235.  
  236.     OSErr    err;
  237.  
  238.     gCursorPtr = nil;
  239.         /* Force re-calc of cursor region and cursor to use. */
  240.  
  241.     if (DisposeAllWindows()) {
  242.         gQuitApplication = true;
  243.         err = noErr;
  244.     }
  245.     else err = errAEEventNotHandled;
  246.         /* All windows didn't close because user cancelled the quit. */
  247.  
  248.     return(err);
  249. }
  250.  
  251.  
  252.  
  253. /*****************************************************************************/
  254.  
  255.  
  256.  
  257. /* Called when we recieve an AppleEvent with an ID of "kAEOpenDocuments".
  258. ** This routine gets the direct parameter, parses it up into little FSSpecs,
  259. ** and opens each indicated file.  It also shows the technique to be used in
  260. ** determining if you are doing everything the AppleEvent record is telling
  261. ** you.  Parameters can be divided up into two groups: required and optional.
  262. ** Before executing an event, you must make sure that you've read all the
  263. ** required events.  This is done by making an "any more?" call to the
  264. ** AppleEvent manager. */
  265.  
  266. #pragma segment AppleEvents
  267. static OSErr    OpenDocEventHandler(AppleEvent *message, AppleEvent *reply, short mode)
  268. {
  269. #pragma unused (reply)
  270.  
  271.     OSErr        err;
  272.     OSErr        err2;
  273.     AEDesc        theDesc;
  274.     FSSpec        theFSS;
  275.     short        loop;
  276.     long        numFilesToOpen;
  277.     AEKeyword    ignoredKeyWord;
  278.     DescType    ignoredType;
  279.     Size        ignoredSize;
  280.     FileRecHndl    frHndl;
  281.     WindowPtr    docWindow;
  282.  
  283.     theDesc.dataHandle = nil;
  284.         /* Make sure disposing of the descriptors is okay in all cases.
  285.         ** This will not be necessary after 7.0b3, since the calls that
  286.         ** attempt to create the descriptors will nil automatically
  287.         ** upon failure. */
  288.  
  289.     if (err = AEGetParamDesc(message, keyDirectObject, typeAEList, &theDesc))
  290.         return(err);
  291.  
  292.     if (!MissedAnyParameters(message)) {
  293.  
  294. /* Got all the parameters we need.  Now, go through the direct object,
  295. ** see what type it is, and parse it up. */
  296.  
  297.         err = AECountItems(&theDesc, &numFilesToOpen);
  298.         if (!err) {
  299.             /* We have numFilesToOpen that need opening, as either a window
  300.             ** or to be printed.  Go to it... */
  301.  
  302.             for (loop = 1; ((loop <= numFilesToOpen) && (!err)); ++loop) {
  303.                 err = AEGetNthPtr(        /* GET NEXT IN THE LIST...         */
  304.                     &theDesc,            /* List of file names.             */
  305.                     loop,                /* Item # in the list.             */
  306.                     typeFSS,            /* Item is of type FSSpec.         */
  307.                     &ignoredKeyWord,    /* Returned keyword -- we know.  */
  308.                     &ignoredType,        /* Returned type -- we know.     */
  309.                     (Ptr)&theFSS,        /* Where to put the FSSpec info. */
  310.                     sizeof(theFSS),        /* Size of the FSSpec info.         */
  311.                     &ignoredSize        /* Actual size -- we know.         */
  312.                 );
  313.                 if (err) break;
  314.  
  315.                 err = OpenDocument(&frHndl, &theFSS, fsRdWrPerm);
  316.                 if (err) break;
  317.  
  318.                 gPrintPage = mode;
  319.                     /* Open the window off-screen if we are printing.
  320.                     ** We use the gPrintPage global to flag this.  Normally, the
  321.                     ** gPrintPage global is to tell ImageDocument if we are imaging
  322.                     ** to the window or to paper.  We don't need it for this yet,
  323.                     ** as we can't image the document until it is opened.  DoNewWindow()
  324.                     ** uses gPrintPage as a flag to open the window off-screen, but
  325.                     ** visible, so that PrintMonitor can use the title of the window
  326.                     ** as the document name that is being printed. */
  327.  
  328.                 if (err = DoNewWindow(frHndl, &docWindow, FrontWindow(), (WindowPtr)-1))
  329.                     DisposeDocument(frHndl);
  330.                 else {
  331.                     if (gPrintPage) {
  332.                         err  = PrintDocument(frHndl, (mode == 2), (loop == 1));
  333.                         mode = 1;    /* No interaction mode (mode == 2) only valid
  334.                                     ** for the first printed document. */
  335.                         DisposeDocument(frHndl);
  336.                         DisposeAnyWindow(docWindow);
  337.                     }
  338.                 }
  339.                 gPrintPage = 0;
  340.                     /* Put the ImageDocument controlling global back to normal. */
  341.             }
  342.         }
  343.     }
  344.     DonePrinting();        /* Clean up after printing, if we did any. */
  345.  
  346.     err2 = AEDisposeDesc(&theDesc);
  347.     return(err ? err : err2);
  348. }
  349.  
  350.  
  351.  
  352.